package io.gitee.chearnee.fw.datasecurity.core.advice;

import io.gitee.chearnee.fw.datasecurity.core.annotation.CryptField;
import io.gitee.chearnee.fw.datasecurity.core.annotation.control.EnableCryptAop;
import io.gitee.chearnee.fw.datasecurity.core.handler.CryptHandlerFactory;
import org.aspectj.lang.annotation.Pointcut;

import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.Optional;

/**
 * @author cn
 * @version 1.0
 * @description
 * @date 11/15/2022 10:57 AM
 */

public class DataCryptAop extends DataSecurityAop<CryptField, EnableCryptAop> {

    protected DataCryptAop() {
        super(CryptField.class);
    }


    /**
     * aop脱敏
     */
    @Pointcut("@annotation(io.gitee.chearnee.fw.datasecurity.core.annotation.control.EnableCryptAop)" +
            "||@within(io.gitee.chearnee.fw.datasecurity.core.annotation.control.EnableCryptAop)")
    @Override
    public void pointcut() {
        //  document why this method is empty
    }

    /**
     * 禁用脱敏
     */
    @Pointcut("@annotation(io.gitee.chearnee.fw.datasecurity.core.annotation.control.DisableCrypt)" +
            "||@within(io.gitee.chearnee.fw.datasecurity.core.annotation.control.DisableCrypt)")
    @Override
    public void disablePointcut() {
        // document why this method is empty
    }

    @Override
    public boolean in(EnableCryptAop t) {
        return t.inDecrypt();
    }

    @Override
    public boolean out(EnableCryptAop t) {
        return t.outEncrypt();
    }

    @Override
    public Object inExecute(DataSecurityAop.SDEntity target) {
        return CryptHandlerFactory.getCryptHandler(target.getObj(), (CryptField) target.getAnnotation()).encrypt(target.getObj(), (CryptField) target.getAnnotation());
    }

    @Override
    public Object outExecute(Object target, Annotation annotation) {
        return CryptHandlerFactory.getCryptHandler(target, (CryptField) annotation).encrypt(target, (CryptField) annotation);
    }

    @Override
    public Optional<Annotation> findAnnotation(Annotation[] param) {
        return Arrays.stream(param).filter(e -> CryptField.class.equals(e.annotationType())).findFirst();
    }
}
